package com.zijidelu.luframework.api.exception;

import com.zijidelu.luframework.api.model.ApiResult;
import com.zijidelu.luframework.base.exception.BizException;
import com.zijidelu.luframework.base.exception.SysException;
import com.zijidelu.luframework.base.message.impl.GenericMessage;
import com.zijidelu.luframework.constant.StringConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.stream.Collectors;

/**
 * 全局异常处理器，用于捕获并处理控制器层抛出的异常。
 *
 * @author zijidelu
 * @datetime 2025/10/16 15:33
 */
@Slf4j
@ControllerAdvice
public class DefaultControllerExceptionHandler implements LuFrameworkControllerExceptionHandler {

    /**
     * 处理业务运行时异常
     *
     * @param ex 业务运行时异常对象
     * @return 封装错误信息的 ApiResult 对象
     */
    @ExceptionHandler(BizException.class)
    @ResponseBody
    public ApiResult<String> handleBizException(BizException ex) {
        log.error("接口运行异常: {}", ex.getMessage(), ex);
        return ApiResult.resolveException(ex);
    }

    /**
     * 处理其他未明确捕获的异常
     *
     * @param ex 异常对象
     * @return 封装错误信息的 ApiResult 对象
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ApiResult<String> handleException(Exception ex) {
        log.error("接口运行异常: {}", ex.getMessage(), ex);
        return ApiResult.failOf(GenericMessage.SYS_EXCEPTION.getCode(), "系统异常，请稍后重试", null);
    }

    /**
     * 处理其他未明确捕获的异常
     *
     * @param ex 异常对象
     * @return 封装错误信息的 ApiResult 对象ø
     */
    @ExceptionHandler(SysException.class)
    @ResponseBody
    public ApiResult<String> handleSysException(SysException ex) {
        log.error("接口运行异常: {}", ex.getMessage(), ex);
        return ApiResult.failOf(GenericMessage.SYS_EXCEPTION.getCode(), "系统异常，请稍后重试", null);
    }

    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiResult<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        log.error("接口参数校验异常: {}", ex.getMessage(), ex);
        String errorMessage = ex.getBindingResult().getFieldErrors()
                .stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(StringConstant.CH_COMMA));
        return ApiResult.failOf(GenericMessage.BIZ_EXCEPTION.getCode(), errorMessage, null);
    }
}